package com.ffyc.resale.web;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.ffyc.resale.dao.ChatDao;
import com.ffyc.resale.model.Chat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Component;
import org.springframework.web.context.annotation.ApplicationScope;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

@ServerEndpoint(value = "/api/websocket/{from}/{to}")
public class WebSocketServer {
    private static Logger log = LoggerFactory.getLogger(WebSocketServer.class);
    private static Map<String, Session> sessions = new ConcurrentHashMap<>();
    private Integer from;
    private Integer to;
    private static ChatDao chatDao;
    // 使用静态方法注入ChatDao
    public static void setChatDao(ChatDao dao) {
        WebSocketServer.chatDao = dao;
    }
    /**
     * 连接创建成功
     *
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("from") Integer from,@PathParam("to")Integer to){
        this.from = from;
        this.to = to;
        String sessionKey = getSessionKey(from, to);
        // 如果已存在连接，先关闭旧连接
        Session oldSession = sessions.get(sessionKey);
        if (oldSession != null) {
            try {
                oldSession.close();
            } catch (IOException e) {
                log.error("关闭旧连接失败", e);
            }
        }
        sessions.put(sessionKey, session);

        log.info("用户连接建立: {} -> {}, 当前连接数: {}", from, to, sessions.size());
    }

    /**
     * 连接关闭
     */
    @OnClose
    public void onClose(){
        String sessionKey = getSessionKey(from, to);
        sessions.remove(sessionKey);
        log.info("用户断开连接: {} -> {}, 剩余连接数: {}", from, to, sessions.size());
    }

    /**
    * 接收消息
    * @param message
    * */
    @OnMessage
    public void onMessage(String message,Session  session){
        try{
            if (chatDao == null) {
                throw new RuntimeException("ChatDao未注入");
            }
            // 1. 构建消息实体
            Chat chat = new Chat();
            chat.setSender(from);
            chat.setReceiver(to);
            chat.setContent(message);
            chat.setTime(new Date());
            chat.setStatus(1); // 1-已发送，2-已读等

            // 2. 保存到数据库
            int result = chatDao.insert(chat);
            if (result <= 0) {
                log.error("消息存储失败: {}", chat);
                return;
            }

            // 3. 转发给目标用户
            String targetKey = getSessionKey(to, from);
            Session targetSession = sessions.get(targetKey);
            if (targetSession != null && targetSession.isOpen()) {
                // 构建标准化消息格式
                Map<String, Object> msg = new HashMap<>();
                msg.put("id", chat.getId()); // 返回数据库生成的ID
                msg.put("sender", from);
                msg.put("receiver", to);
                msg.put("content", message);
                msg.put("timestamp", System.currentTimeMillis());
                // 创建 ObjectMapper 实例
                ObjectMapper objectMapper = new ObjectMapper();
                targetSession.getAsyncRemote().sendText(objectMapper.writeValueAsString(msg));
            }
            log.info("消息已存储并转发: {} -> {}, 内容: {}", from, to, message);
        } catch (Exception e) {
            log.error("消息处理异常", e);
            try {
                session.getBasicRemote().sendText("消息发送失败: " + e.getMessage());
            } catch (IOException ex) {
                log.error("错误反馈发送失败", ex);
            }
        }
    }
    private String getSessionKey(Integer user1, Integer user2) {
        return user1 + "_" + user2;
    }
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("WebSocket错误", error);
        try {
            session.close();
        } catch (IOException e) {
            log.error("关闭错误会话失败", e);
        }
    }
}
